#pragma once
#include<iostream>
#include<pthread.h>
#include<string>
#include<functional>

template<class T>
using func_t = std::function<void(T&)>;


template<class T>
class Thread
{
public:
    Thread(std::string name,func_t<T> func,T data)
        :_tid(0),_name(name),_func(func),_isrunning(false),_data(data)
    {}

    
    static void* ThreadRoute(void* arg)
     {
         Thread* _this = static_cast< Thread*>(arg);
        _this->_func(_this->_data); 
        
        return nullptr;
     }
     
    bool Start()
    {
         int n = pthread_create(&_tid,nullptr,ThreadRoute,this);
         if(n == 0) 
         {
            _isrunning = true;
            return true;
         }
         return false;;
    }

      
    bool Join()
    {
        if(!_isrunning) return true;
        int n = pthread_join(_tid,nullptr);
        if(n == 0)
        {
            _isrunning = false;
            return true;
        }
        return false;
        
    }


    std::string GetThreadName()
    {
        return _name;
    }
    bool isrunning()
    {
        return _isrunning;
    }

private:
    pthread_t _tid; 
    std::string _name;
    func_t<T> _func;
    bool _isrunning;
    T _data;
};


